<template>
  <view class="page-container">
    <!-- 微信小程序专用容器 -->
    <!-- #ifdef MP-WEIXIN -->
    <view 
      class="mp-wrapper" 
      :style="{ 
        paddingBottom: keyboardHeight > 0 ? (keyboardHeight + 'px') : safeAreaBottom + 'px',
        height: windowInnerHeight ? (windowInnerHeight + 'px') : '100vh'
      }"
    >
    <!-- #endif -->
    
    <!-- 固定头部 -->
    <view class="fixed-header">
      <view class="header">
        <view class="back-button" @click="goBack">
          <image class="back-icon" src="/static/back.png" mode="aspectFit"></image>
        </view>
        <text class="page-title">AI助手</text>
      </view>
    </view>

    <!-- 主内容区域 -->
    <view class="main-content" :style="{ marginTop: (statusBarHeight + 80) + 'px', paddingBottom: (inputAreaHeight + 170) + 'px' }">
      <scroll-view 
        class="chat-content" 
        scroll-y="true" 
        :scroll-into-view="scrollToView"
        :scroll-with-animation="false"
        :style="{ height: 'calc(100vh - ' + (statusBarHeight + 50 + inputAreaHeight + 80) + 'px)' }"
      >
        <view class="messages-container">
          <view v-for="(msg, idx) in messages" 
            :key="idx" 
            :id="'msg-'+idx" 
            :class="['msg-row', msg.role]"
          >
            <template v-if="msg.thinking">
              <view class="thinking-line">{{ msg.text }}</view>
            </template>
            <template v-else>
            <view class="msg-bubble" :class="msg.role">
                <template v-if="msg.type==='image'">
                  <image :src="msg.url" class="msg-image" mode="aspectFill" @click="previewImage(msg.url)" />
                </template>
                <template v-else>
                  <text @longpress="copyToClipboard(msg.text)">{{ msg.text }}</text>
                </template>
            </view>
              <!-- AI 文本消息复制按钮 -->
              <view v-if="msg.role==='ai' && msg.type!=='image'" class="msg-copy-row ai">
                <image class="msg-copy-icon" src="/static/copy.png" mode="aspectFit" @click.stop="copyToClipboard(msg.text)" />
              </view>
            </template>
        </view>
        </view>
        <!-- 底部锚点 -->
        <view id="chat-bottom" style="width:100%;height:1px;"></view>
      </scroll-view>
    </view>

    <!-- 固定底部输入区域 -->
    <view 
      class="fixed-bottom-input" 
      :style="{ 
        bottom: keyboardHeight > 0 ? (keyboardHeight + 'px') : safeAreaBottom + 'px',
        transform: isAndroid || isHarmonyOS ? (keyboardHeight > 0 ? 'translateY(0)' : 'none') : 'none'
      }"
    >
      <!-- 功能按钮区 -->
      <view class="function-buttons">
        <view class="function-btn" @click="startNewChat">
          <text class="function-btn-text">新对话</text>
        </view>
        <view class="function-btn" @click="openHistory">
          <text class="function-btn-text">历史对话</text>
        </view>
      </view>
      
      <view class="input-wrapper">
        <view class="input-row">
          <textarea
            v-model="inputText"
            class="bottom-input"
            :placeholder="inputFocused ? '' : '有什么问题尽管问我'"
            confirm-type="done"
            @confirm="sendMessage"
            :disabled="loading"
            caret-color="#19c59c"
            ref="inputRef"
            @focus="onInputFocus"
            @blur="onInputBlur"
            @input="adjustHeight"
            :style="{ height: textareaHeight + 'px' }"
            auto-height
          />
        </view>
        <view class="tools-row">
          <view v-if="attachments.length" class="input-attachments-list">
            <view v-for="(file, idx) in attachments" :key="'att-'+idx" class="input-attachment-item">
              <template v-if="file.type==='image'">
                <image class="input-attachment-img" :src="file.path" mode="aspectFill" />
              </template>
              <template v-else>
                <image class="input-attachment-img" src="/static/wenjian.png" mode="aspectFit" />
              </template>
              <view class="input-attachment-overlay" @click.stop="removeAttachment(idx)">
                <text class="input-attachment-close">✕</text>
              </view>
            </view>
          </view>
          <view class="input-attach-btn" @click="chooseFile">
            <image class="input-attach-img" src="/static/fj.png" mode="aspectFit" />
          </view>
          <view class="input-send-btn" @click="canSend && sendMessage()">
            <image
              class="input-status-img"
              :src="canSend ? '/static/fs1.png' : '/static/fs1.png'"
              mode="aspectFit"
            />
          </view>
        </view>
      </view>
    </view>

    <!-- 历史对话侧边栏 -->
    <view v-if="showHistory" class="history-mask" @click.self="closeHistory">
      <view class="history-drawer">
        <view class="history-header" :style="{ paddingTop: (statusBarHeight + 20) + 'px' }">
          <text class="history-title">历史对话</text>
        </view>
        <scroll-view scroll-y="true" class="history-list">
          <view v-for="(group, gIdx) in groupedHistory" :key="gIdx" class="history-date-group">
            <text class="history-date">{{ group.date }}</text>
            <view v-for="session in group.sessions" :key="session.id" class="history-item" @click="viewSession(session)">
              <text class="history-item-title">{{ session.title }}</text>
            </view>
          </view>
        </scroll-view>
      </view>
    </view>
    
    <!-- #ifdef MP-WEIXIN -->
    </view>
    <!-- #endif -->
  </view>
</template>

<script>
export default {
  data() {
    return {
      statusBarHeight: 0,
      showChat: false,
      messages: [],
      inputText: '',
      userAvatar: 'https://img1.baidu.com/it/u=123456789,123456789&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200',
      aiAvatar: '/static/logo-zgai.png',
      scrollToView: '',
      fromPage: 'home',
      loading: false,
      attachments: [],
      uploadingFiles: [],
      inputFocused: false,
      textareaHeight: 40,
      aiApiUrl: 'http://localhost/v1/chat-messages',
      apiKey: 'app-O863GQrLRMdaFgSSLzyxc9LK',
      showHistory: false,
      historySessions: [],
      sessionHasContent: false,
      currentSession: { title: '', messages: [] },
      isStreaming: false,
      userName: '访客',
      userPosition: '求职者',
      userExperience: '0',
      extraInputs: {
        name: '访客',
        position: '求职者',
        experience: '0',
        education: '本科'
      },
      jobTitle: '',
      companyName: '',
      keyboardHeight: 0, // 键盘高度
      safeAreaBottom: 0, // 底部安全区域高度
      windowHeight: 0, // 窗口高度
      windowInnerHeight: 0, // 实时窗口高度（用于键盘适配）
      isIOS: false, // 是否为iOS系统
      isHarmonyOS: false, // 是否为鸿蒙系统
      isAndroid: false, // 是否为安卓系统
      keyboardAnimating: false, // 键盘动画中
      inputAreaHeight: 120, // 输入区域高度
    }
  },
  computed: {
    canSend() {
      return (this.inputText && this.inputText.trim().length > 0) || this.attachments.length > 0
    },
    groupedHistory() {
      const map = {};
      this.historySessions.forEach(s => {
        if (!map[s.date]) map[s.date] = [];
        map[s.date].push(s);
      });
      return Object.keys(map).sort().reverse().map(date => ({ date, sessions: map[date].sort((a,b)=>b.id-a.id) }));
    }
  },
  onLoad(options) {
    const sys = uni.getSystemInfoSync();
    this.statusBarHeight = sys.statusBarHeight || 0;
    this.windowHeight = sys.windowHeight || 0;
    this.windowInnerHeight = sys.windowHeight || 0; // 初始化为窗口高度
    
    // 检测系统类型
    this.isIOS = sys.platform === 'ios';
    this.isAndroid = sys.platform === 'android';
    this.isHarmonyOS = sys.brand === 'HUAWEI' || sys.model.includes('HUAWEI') || sys.model.includes('HONOR');
    
    // 获取底部安全区域高度
    this.safeAreaBottom = 0;
    // #ifdef MP-WEIXIN
    if (sys.safeAreaInsets && sys.safeAreaInsets.bottom) {
      this.safeAreaBottom = sys.safeAreaInsets.bottom;
    }
    // #endif
    
    // 记录来源页面
    if (options && options.from) {
      this.fromPage = options.from;
    }
    // 处理从job-detail页面传递的参数
    if (options && options.from === 'job-detail') {
      this.jobTitle = decodeURIComponent(options.jobTitle || '');
      this.companyName = decodeURIComponent(options.companyName || '');
      // 如果是从职位详情页面来的，自动切换到练面试模式
      this.activeTab = 1;
      // 设置初始欢迎消息
      this.setInterviewWelcomeMessage();
    }
    // 检查是否有从前一个页面传递的消息需要处理
    if (options && options.fromChat) {
      this.handlePendingMessage();
    }
    
    // 监听键盘高度变化 - 仅在微信小程序中有效
    // #ifdef MP-WEIXIN
    const that = this;
    wx.onKeyboardHeightChange && wx.onKeyboardHeightChange(function(res) {
      that.handleKeyboardChange(res.height);
    });
    
    // 监听窗口尺寸变化，用于安卓/鸿蒙系统适配
    uni.onWindowResize((res) => {
      this.windowInnerHeight = res.size.windowHeight;
      // 在安卓和鸿蒙系统中，键盘弹起时调整容器高度
      if ((this.isAndroid || this.isHarmonyOS) && this.keyboardHeight > 0) {
        this.$forceUpdate();
      }
    });
    // #endif
  },
  methods: {
    goBack() {
      uni.redirectTo({
        url: '/pages/ai-chat/index'
      });
    },
    // changeTab 方法不再需要，可以删除
    handlePendingMessage() {
      // 获取从上一个页面传递的消息数据
      const pendingMessage = uni.getStorageSync('pendingMessage');
      if (pendingMessage) {
        // 清除存储的数据
        uni.removeStorageSync('pendingMessage');
        
        // 切换到聊天模式
        this.showChat = true;
        
        // 处理文本消息
        if (pendingMessage.inputText && pendingMessage.inputText.trim()) {
          this.inputText = pendingMessage.inputText;
        }
        
        // 处理附件
        if (pendingMessage.attachments && pendingMessage.attachments.length > 0) {
          this.attachments = pendingMessage.attachments;
        }
        
        // 延迟100ms后自动发送消息
        setTimeout(() => {
          this.sendMessage();
        }, 100);
      }
    },
    setInterviewWelcomeMessage() {
      if (this.jobTitle && this.companyName) {
        const welcomeMessage = {
          role: 'ai',
          text: `欢迎来到AI面试练习！我来帮你练习${this.companyName}的${this.jobTitle}岗位面试。请先简单介绍一下你的背景和求职意向，然后我会根据这个岗位的要求开始提问。准备好了吗？`,
          type: 'text'
        };
        this.messages.push(welcomeMessage);
        this.currentSession.messages.push(welcomeMessage);
        this.showChat = true;
      } else if (this.jobTitle) {
        const welcomeMessage = {
          role: 'ai',
          text: `欢迎来到AI面试练习！我来帮你练习${this.jobTitle}岗位的面试。请先简单介绍一下你的背景和求职意向，然后我会根据这个岗位的要求开始提问。准备好了吗？`,
          type: 'text'
        };
        this.messages.push(welcomeMessage);
        this.currentSession.messages.push(welcomeMessage);
        this.showChat = true;
      }
    },
    async sendMessage() {
      if ((!this.canSend && this.attachments.length===0) || this.loading) return;
      if (!this.showChat) this.showChat = true;

      // 标记loading
      this.loading = true;

      /* --------  处理附件  -------- */
      if (this.attachments.length > 0) {
        const currentAttachments = [...this.attachments];
        for (const file of currentAttachments) {
          if (file.type === 'image') {
            const imgMsg = { role: 'user', type: 'image', url: file.path };
            this.messages.push(imgMsg);
            this.currentSession.messages.push(imgMsg);
          } else {
            const fileMsg = { role: 'user', text: file.name };
            this.messages.push(fileMsg);
            this.currentSession.messages.push(fileMsg);
          }
          this.sessionHasContent = true;
        }
        this.attachments = [];
      }

      /* --------  处理文本  -------- */
      if (this.inputText && this.inputText.trim().length>0) {
        const userMsg = { role: 'user', text: this.inputText, type: 'text' };
        this.messages.push(userMsg);
        this.currentSession.messages.push(userMsg);
        this.sessionHasContent = true;
        this.inputText = '';
        this.textareaHeight = 40;
      }

      // 立即滚动到底部，显示用户消息
      this.$nextTick(() => {
        this.scrollToBottom();
      });

      /* --------  调用大模型接口  -------- */
      const aiPlaceholder = { role: 'ai', text: '思考中...', thinking: true };
      this.messages.push(aiPlaceholder);
      this.currentSession.messages.push(aiPlaceholder);
      
      // 再次滚动，显示AI思考状态
      this.$nextTick(() => {
        this.scrollToBottom();
      });

      try {
        await this.streamAIResponse(aiPlaceholder, this.messages);
      } catch(e) {
        console.error('AI接口错误:', e);
        aiPlaceholder.text = '大模型接口调用失败，请稍后再试。';
        aiPlaceholder.thinking = false;
      } finally {
        this.loading = false;
      }
    },
    chooseFile() {
      const that = this;
      uni.showActionSheet({
        itemList: ['图片', '文档'],
        success(res) {
          if (res.tapIndex === 0) {
            // 选择图片
            uni.chooseImage({
              count: 9,
              sizeType: ['original', 'compressed'],
              sourceType: ['album', 'camera'],
              success(imgRes) {
                imgRes.tempFiles.forEach(file => {
                  that.handleAttachment({
                    type: 'image',
                    name: file.name || '图片',
                    path: file.path
                  });
                });
              },
              fail(err) {
                console.log('选择图片失败：', err);
                uni.showToast({ 
                  title: '选择图片失败', 
                  icon: 'none',
                  duration: 2000
                });
              }
            });
          } else if (res.tapIndex === 1) {
            // 选择文档 - 微信小程序支持度有限
            // #ifdef MP-WEIXIN
            uni.chooseMessageFile({
              count: 1,
              type: 'file',
              success(fileRes) {
                fileRes.tempFiles.forEach(file => {
                  that.handleAttachment({
                    type: 'file',
                    name: file.name,
                    path: file.path
                  });
                });
              },
              fail(err) {
                console.log('选择文件失败：', err);
                uni.showToast({ 
                  title: '选择文件失败', 
                  icon: 'none',
                  duration: 2000
                });
              }
            });
            // #endif
            // #ifndef MP-WEIXIN
            uni.showToast({ 
              title: '该平台暂不支持文件选择', 
              icon: 'none',
              duration: 2000
            });
            // #endif
          }
        }
      });
    },
    onH5FileChange(e) {
      const files = e.target.files;
      if (!files || !files.length) return;
      Array.from(files).forEach(file => {
        this.handleAttachment({
          type: 'file',
          name: file.name,
          path: '',
          fileObj: file
        });
      });
    },
    async handleAttachment(file) {
      // 若已达到最大数量，提示并返回
      const MAX_ATTACHMENTS = 5;
      if (this.attachments.length >= MAX_ATTACHMENTS) {
        uni.showToast({ title: `至多支持上传${MAX_ATTACHMENTS}个附件`, icon: 'none' });
        return;
      }
      // 预留上传/接口逻辑
      // 可在此处上传文件到服务器，获取url后再推送到消息流
      // 上传进度模拟/预留
      const uploadItem = { name: file.name, progress: 0 };
      this.uploadingFiles.push(uploadItem);
      const simulate = setInterval(() => {
        if (uploadItem.progress < 100) {
          uploadItem.progress += 10;
        } else {
          clearInterval(simulate);
          // 上传完成，加入输入框附件区
          this.attachments.push(file);
          // 移除进度条
          this.uploadingFiles = this.uploadingFiles.filter(f => f !== uploadItem);
        }
      }, 120);
    },
    removeAttachment(idx) {
      this.attachments.splice(idx, 1);
    },
    onInputFocus() {
      this.inputFocused = true;
      // 针对不同系统调整输入框位置
      if (this.isAndroid || this.isHarmonyOS) {
        // 安卓和鸿蒙系统直接滚动到底部
        setTimeout(() => {
          this.scrollToBottom();
        }, 100);
      } else {
        // 非安卓/鸿蒙系统（如iOS）的处理
        setTimeout(() => {
          this.scrollToBottom();
        }, 300);
      }
    },
    onInputBlur() {
      this.inputFocused = false;
      // 隐藏键盘时重置高度
      if (this.keyboardHeight > 0) {
        this.keyboardHeight = 0;
        this.$forceUpdate();
      }
    },
    adjustHeight(e) {
      // 微信小程序textarea自适应高度处理
      const maxHeight = 120;
      
      // #ifdef MP-WEIXIN
      const detail = e.detail || {};
      const height = detail.height || 40;
      this.textareaHeight = Math.min(maxHeight, Math.max(40, height));
      // #endif
      
      // #ifndef MP-WEIXIN
      const h = e.detail && e.detail.height ? e.detail.height : 40;
      this.textareaHeight = Math.min(maxHeight, h);
      // #endif
      
      // 更新输入区域高度
      this.updateInputAreaHeight();
    },
    
    // 键盘高度变化处理
    handleKeyboardChange(height) {
      console.log('键盘高度变化:', height);
      this.keyboardAnimating = true;
      this.keyboardHeight = height;
      
      // 更新输入区域高度
      this.updateInputAreaHeight();
      
      this.$nextTick(() => {
        this.$forceUpdate();
        if (height > 0) {
          // 键盘弹出时滚动到底部
          setTimeout(() => {
            this.scrollToBottom();
            this.keyboardAnimating = false;
          }, this.isIOS ? 300 : 100);
        } else {
          this.keyboardAnimating = false;
        }
      });
    },
    
    // 更新输入区域高度
    updateInputAreaHeight() {
      // 基础高度：功能按钮 + 输入框 + 工具栏
      let baseHeight = 120; // 默认高度
      
      // 加上文本域高度变化
      if (this.textareaHeight > 40) {
        baseHeight += (this.textareaHeight - 40);
      }
      
      // 加上附件列表高度
      if (this.attachments.length > 0) {
        baseHeight += 50; // 附件列表高度
      }
      
      // 针对安卓和鸿蒙系统进行优化
      if ((this.isAndroid || this.isHarmonyOS) && this.keyboardHeight > 0) {
        // 当键盘弹起时，减少输入区域高度以减少间距
        this.inputAreaHeight = Math.max(80, baseHeight - 20);
      } else {
        this.inputAreaHeight = baseHeight;
      }
    },
    copyToClipboard(text) {
      uni.setClipboardData({
        data: text,
        success: () => {
          uni.showToast({ title: '已复制', icon: 'none', duration: 1000 });
        },
        fail: () => {
          uni.showToast({ title: '复制失败', icon: 'none', duration: 1500 });
        }
      });
    },
    /* 预留大模型接口方法 */
    async fetchAIResponse(conversation) {
      const MAX_CONTEXT = 20;
      const messagesToSend = conversation.slice(-MAX_CONTEXT);
      const lastUser = messagesToSend.reverse().find(m=>m.role==='user');
      const query = lastUser?.text || '...';
      const payload = {
        inputs: { ...this.extraInputs },
        query,
        response_mode: 'blocking',
        conversation_id: '',
        user: 'abc-123'
      };
      try {
        const res = await uni.request({
          url: this.aiApiUrl,
          method: 'POST',
          header: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${this.apiKey}`
          },
          data: payload,
          timeout: 20000
        });
        const { statusCode, data } = res;
        if (statusCode === 200 && data && data.answer) {
          return data.answer;
        }
        throw new Error('Invalid response');
      } catch(e){
        console.error(e);
        return '大模型接口调用失败';
      }
    },
    previewImage(url) {
      uni.previewImage({
        urls: [url],
        current: url
      });
    },
    openHistory() {
      this.loadHistory();
      this.showHistory = true;
    },
    closeHistory() {
      this.showHistory = false;
    },
    loadHistory() {
      const stored = uni.getStorageSync('chatHistory') || [];
      this.historySessions = stored;
    },
    saveCurrentSession() {
      if (!this.sessionHasContent) return;
      const firstUserMsg = this.currentSession.messages.find(m => m.role === 'user');
      let title = '文件上传';
      if (firstUserMsg) {
        if (firstUserMsg.text) title = firstUserMsg.text.substring(0, 30);
      }
      const dateStr = new Date().toISOString().slice(0, 10);
      const sessionObj = {
        id: Date.now(),
        date: dateStr,
        title,
        messages: this.currentSession.messages
      };
      const stored = uni.getStorageSync('chatHistory') || [];
      stored.push(sessionObj);
      uni.setStorageSync('chatHistory', stored);
      this.sessionHasContent = false;
      this.currentSession = { title: '', messages: [] };
    },
    viewSession(session) {
      // 深拷贝，防止修改原历史
      this.messages = JSON.parse(JSON.stringify(session.messages));
      this.showChat = true;
      this.closeHistory();
      this.scrollToBottom();
    },
    startNewChat() {
      // 若当前无任何消息且未开始会话，则提示
      if (!this.sessionHasContent && this.messages.length === 0) {
        uni.showToast({ title: '已是最新对话', icon: 'none' });
        return;
      }
      // 清空当前会话开始新的对话
      this.messages = [];
      this.attachments = [];
      this.currentSession = { title:'', messages:[] };
      this.showChat = false;
      this.scrollToView = '';
      this.sessionHasContent = false;
    },
    /* --------  新增：流式响应方法  -------- */
    async streamAIResponse(placeholder, conversation) {
      if (this.isStreaming) return;
      this.isStreaming = true;
      const MAX_CONTEXT = 20;
      const messagesToSend = conversation.slice(-MAX_CONTEXT);
      const lastUser = messagesToSend.slice().reverse().find(m=>m.role==='user');
      const query = lastUser?.text || '...';
      const payload = {
        inputs: { ...this.extraInputs },
        query,
        response_mode: 'streaming',
        conversation_id: '',
        user: 'abc-123'
      };

      // 公用结束回调
      const finish = () => { this.isStreaming = false; };

      /* -------- H5 平台实现（Fetch + ReadableStream） -------- */
      // #ifdef H5
      try {
        const res = await fetch(this.aiApiUrl, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${this.apiKey}`,
            'Accept': 'text/event-stream'
          },
          body: JSON.stringify(payload)
        });
        if (!res.ok || !res.body) throw new Error('Network response was not ok');
        const reader = res.body.getReader();
        const decoder = new TextDecoder('utf-8');
        let full = '';
        while (true) {
          const { value, done } = await reader.read();
          if (done) break;
          const chunk = decoder.decode(value, { stream: true });
          const lines = chunk.split(/\r?\n/);
          for (const line of lines) {
            const trimmed = line.trim();
            if (!trimmed || !trimmed.startsWith('data:')) continue;
            const dataStr = trimmed.replace(/^data:\s*/, '');
            if (dataStr === '[DONE]') { finish(); return full; }
            try {
              const json = JSON.parse(dataStr);
              const chunkText = json.answer || json.data || json.delta || json.content || '';
              if (chunkText) {
                if (placeholder.thinking) { placeholder.thinking = false; placeholder.text = ''; }
                full += chunkText;
                placeholder.text = full;
                this.$forceUpdate();
                this.scrollToBottom();
              }
            } catch(e) { /* 忽略解析错误 */ }
          }
        }
        finish();
        return full;
      } catch(err) {
        finish();
        throw err;
      }
      // #endif

      /* -------- 微信小程序实现（requestTask.onChunkReceived） -------- */
      // #ifdef MP-WEIXIN
      return new Promise((resolve, reject)=>{
        try {
          const task = uni.request({
            url: this.aiApiUrl,
            method: 'POST',
            header: {
              'Content-Type': 'application/json',
              'Authorization': `Bearer ${this.apiKey}`,
              'Accept': 'text/event-stream'
            },
            data: payload,
            enableChunked: true,
            timeout: 30000,
            success: (res)=>{ 
              // 最终回调，若未使用流式返回，此处可作为兜底
              if (full === '' && res.data && res.data.answer) {
                full = res.data.answer;
                placeholder.text = full;
                placeholder.thinking = false;
                finish();
                resolve(full);
              }
            },
            fail: (err)=>{ 
              console.error('请求失败:', err);
              finish(); 
              reject(err); 
            }
          });
          let full = '';
          // 新版基础库支持 onChunkReceived
          task?.onChunkReceived?.((resp)=>{
            // resp.data 为 ArrayBuffer
            const chunk = new TextDecoder('utf-8').decode(resp.data);
            const lines = chunk.split(/\r?\n/);
            lines.forEach(line=>{
              const trimmed = line.trim();
              if (!trimmed.startsWith('data:')) return;
              const dataStr = trimmed.replace(/^data:\s*/, '');
              if (dataStr === '[DONE]') { finish(); resolve(full); return; }
              try {
                const json = JSON.parse(dataStr);
                const chunkText = json.answer || json.data || json.delta || json.content || '';
                if (chunkText) {
                  if (placeholder.thinking) { placeholder.thinking = false; placeholder.text = ''; }
                  full += chunkText;
                  placeholder.text = full;
                  this.$forceUpdate();
                  this.scrollToBottom();
                }
              } catch(e) {}
            });
          });
        } catch(e) { finish(); reject(e); }
      });
      // #endif

      /* -------- App 平台实现（plus.net.XMLHttpRequest） -------- */
      // #ifdef APP-PLUS
      return new Promise((resolve, reject)=>{
        try {
          const xhr = new plus.net.XMLHttpRequest();
          xhr.open('POST', this.aiApiUrl);
          xhr.setRequestHeader('Content-Type', 'application/json');
          xhr.setRequestHeader('Authorization', `Bearer ${this.apiKey}`);
          xhr.setRequestHeader('Accept', 'text:event-stream');
          let full = '';
          xhr.onreadystatechange = () => {
            if (xhr.readyState === 3 || xhr.readyState === 4) { // 正在接收 || 完成
              const chunk = xhr.responseText.substring(full.length);
              const lines = chunk.split(/\r?\n/);
              lines.forEach(line=>{
                const trimmed = line.trim();
                if (!trimmed.startsWith('data:')) return;
                const dataStr = trimmed.replace(/^data:\s*/, '');
                if (dataStr === '[DONE]') { finish(); resolve(full); return; }
                try {
                  const json = JSON.parse(dataStr);
                  const chunkText = json.answer || json.data || json.delta || json.content || '';
                  if (chunkText) {
                    if (placeholder.thinking) { placeholder.thinking = false; placeholder.text = ''; }
                    full += chunkText;
                    placeholder.text = full;
                    this.$forceUpdate();
                    this.scrollToBottom();
                  }
                } catch(e) {}
              });
            }
            if (xhr.readyState === 4 && xhr.status !== 200) {
              finish(); reject(new Error('Network error'));
            }
          };
          xhr.send(JSON.stringify(payload));
        } catch(e) { finish(); reject(e); }
      });
      // #endif

      /* -------- 其它平台或不支持流式时的兜底 -------- */
      const answer = await this.fetchAIResponse(conversation);
      placeholder.text = answer;
      finish();
      return answer;
    },
    /* 滚动到底部（通过重置 scrollToView 实现连续多次滚动） */
    scrollToBottom(){
      this.scrollToView = '';
      this.$nextTick(()=>{ 
        this.scrollToView = 'chat-bottom'; 
        // 再次确保滚动生效
        setTimeout(() => {
          this.scrollToView = 'chat-bottom';
        }, 50);
      });
    },
  },
  onHide() {
    this.saveCurrentSession();
    // #ifdef MP-WEIXIN
    // 页面隐藏时重置键盘高度
    this.keyboardHeight = 0;
    this.keyboardAnimating = false;
    // #endif
  },
  onUnload() {
    this.saveCurrentSession();
    // #ifdef MP-WEIXIN
    // 页面销毁时清理键盘监听
    wx.offKeyboardHeightChange && wx.offKeyboardHeightChange();
    this.keyboardHeight = 0;
    this.keyboardAnimating = false;
    // #endif
  },
  // #ifdef MP-WEIXIN
  onShow() {
    // 页面显示时重新获取系统信息
    const sys = uni.getSystemInfoSync();
    this.windowHeight = sys.windowHeight || this.windowHeight;
    this.windowInnerHeight = sys.windowHeight || this.windowInnerHeight;
    // 重新检测系统类型（防止系统更新后变化）
    this.isIOS = sys.platform === 'ios';
    this.isAndroid = sys.platform === 'android';
    this.isHarmonyOS = sys.brand === 'HUAWEI' || sys.model.includes('HUAWEI') || sys.model.includes('HONOR');
  },
  // #endif
}
</script>

<style scoped>
@keyframes fadeInBubble {
  from {
    opacity: 0;
    transform: translateY(20rpx) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
@keyframes float {
  0% { transform: translateY(0); }
  50% { transform: translateY(-18rpx); }
  100% { transform: translateY(0); }
}
@keyframes breathe {
  0% { transform: scale(1); }
  50% { transform: scale(1.08); }
  100% { transform: scale(1); }
}
.chat-default-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 60vh;
  width: 100%;
  text-align: center;
  margin-top: 2vh;
}
.logo-wave-wrap {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 120rpx;
  width: 120rpx;
  margin-bottom: 32rpx;
}
.logo-wave {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 120rpx;
  height: 120rpx;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgba(25,197,156,0.18);
  animation: wavePulse 2.2s infinite;
  z-index: 0;
}
.logo-wave2 {
  animation-delay: 0.5s;
}
.logo-wave3 {
  animation-delay: 1s;
}
@keyframes wavePulse {
  0% {
    opacity: 0.7;
    transform: translate(-50%, -50%) scale(1);
  }
  70% {
    opacity: 0.2;
    transform: translate(-50%, -50%) scale(1.7);
  }
  100% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(2);
  }
}
.default-logo {
  position: relative;
  z-index: 1;
  height: 120rpx;
  width: 120rpx;
  border-radius: 50%;
  background: #f6f6f6;
  animation: breathe 2.2s ease-in-out infinite;
  margin-bottom: 24rpx;
}
.default-title {
  font-size: 36rpx;
  font-weight: bold;
  margin-bottom: 18rpx;
  color: #222;
}
.default-desc {
  font-size: 28rpx;
  color: #888;
  line-height: 1.7;
  max-width: 80vw;
}
/* 页面容器 */
.page-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: linear-gradient(
    180deg,
    #F0FDF8 0%,
    #E6FAF5 20%,
    #D0F0EE 50%,
    #E8F5E4 80%,
    #F8FBF8 95%,
    #FFFFFF 100%
  );
}

/* 微信小程序容器 */
/* #ifdef MP-WEIXIN */
.mp-wrapper {
  width: 100%;
  height: 100vh;
  position: relative;
  overflow: hidden;
  transition: padding-bottom 0.3s ease;
}
/* #endif */

/* 固定头部 */
.fixed-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  background: transparent;
}

.header {
  position: relative;
  background: transparent;
  padding: 110rpx 36rpx 40rpx;
  color: #333333;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 10;
}

.back-button {
  position: absolute;
  top: 98rpx;
  left: 36rpx;
  z-index: 10;
  width: 64rpx;
  height: 64rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(16, 185, 129, 0.15);
  backdrop-filter: blur(20rpx);
  border: 2rpx solid rgba(16, 185, 129, 0.2);
  box-shadow:
    0 8rpx 20rpx rgba(0, 0, 0, 0.15),
    inset 0 2rpx 4rpx rgba(255, 255, 255, 0.1);
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  cursor: pointer;
}

.back-button:active {
  transform: scale(0.9) translateY(2rpx);
  background: rgba(16, 185, 129, 0.25);
  box-shadow:
    0 4rpx 12rpx rgba(0, 0, 0, 0.2),
    inset 0 2rpx 4rpx rgba(255, 255, 255, 0.2);
}

.back-icon {
  width: 36rpx;
  height: 36rpx;
  opacity: 0.8;
  transition: opacity 0.3s ease;
  filter: brightness(0);
}

.back-icon:active {
  opacity: 1;
}

.page-title {
  font-size: 36rpx;
  font-weight: 700;
  color: #222;
  text-align: center;
}

/* 主内容区域 */
.main-content {
  position: relative;
  overflow: hidden;
}

.chat-content {
  width: 100%;
  padding: 20rpx;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.messages-container {
  padding-bottom: 10rpx; /* 输入区+tabbar+安全间距 */
}
.msg-row {
  position: relative;
  display: flex;
  align-items: flex-end;
  margin-bottom: 40rpx;
}
.msg-row.user {
  flex-direction: row-reverse;
}
.msg-row.ai {
  flex-direction: row;
}
.msg-bubble {
  max-width: 75vw;
  padding: 28rpx 36rpx;
  font-size: 30rpx;
  line-height: 1.7;
  word-break: break-all;
  box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.06);
  border: 1.5rpx solid transparent;
  backdrop-filter: blur(2px);
  animation: fadeInBubble 0.5s cubic-bezier(.39,.58,.57,1.15);
  margin-bottom: 0;
  position: relative;
}
.msg-bubble.user {
  background: #fff;
  color: #222;
  border: 1.5rpx;
  box-shadow: 0 2rpx 6rpx rgba(0,0,0,0.07);
  border-radius:40rpx;
  border-bottom-right-radius: 6rpx;
}
.msg-bubble.ai {
  background: linear-gradient(135deg, #e6faf5 60%, #eafcff 100%);
  color: #17446e;
  border: 1.5rpx;
  box-shadow: 0 2rpx 6rpx rgba(110,244,204,0.10);
    border-radius:40rpx;
  border-top-left-radius: 6rpx;
}
.quick-suggest-row,
.quick-suggest-scroll,
.quick-suggest-item {
  display: none !important;
}
.chat-input-row {
  display: flex;
  align-items: center;
  background: rgba(255,255,255,0.85);
  padding: 16rpx 24rpx 32rpx 24rpx;
  border-top: 1rpx solid #e0f7fa;
  backdrop-filter: blur(6px);
}
.chat-input {
  flex: 1;
  border: none;
  outline: none;
  font-size: 28rpx;
  background: #f7f8fa;
  border-radius: 24rpx;
  padding: 16rpx 24rpx;
  margin-right: 16rpx;
  box-shadow: 0 2rpx 8rpx rgba(15,211,255,0.08);
  border: 1rpx solid #e0f7fa;
}
.send-btn {
  background: linear-gradient(90deg, #00b386 0%, #0fd3ff 100%);
  color: #fff;
  border: none;
  border-radius: 20px;
  padding: 0 28px;
  height: 40px;
  font-size: 16px;
  margin-left: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(15,211,255,0.08);
  transition: transform 0.15s cubic-bezier(.39,.58,.57,1.15);
}
.send-btn:active {
  transform: scale(0.95);
}
.tabbar {
  margin-bottom: 0rpx;
  flex-direction: row;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 16rpx;
  height: 112rpx;
  background: rgba(255,255,255,0.72);
  display: flex;
  justify-content: space-around;
  align-items: center;
  /* 更强的悬浮阴影效果 */
  box-shadow: 0 12rpx 36rpx 0 rgba(0,0,0,0.18), 0 2rpx 8rpx 0 rgba(0,0,0,0.08);
  border-radius: 24rpx;
  margin-left: 18rpx;
  margin-right: 18rpx;
  width: calc(100vw - 36rpx);
  backdrop-filter: blur(18px);
  z-index: 999;
  border: none;
}
.tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #888;
  font-size: 22rpx;
  flex: 1;
  justify-content: center;
  padding: 0;
  gap: 4rpx;
}
.tab.active {
  color: #00b386;
}
.tab-icon {
  width: 44rpx;
  height: 44rpx;
  margin-bottom: 0;
}
.tab-label {
  font-size: 20rpx;
  margin-top: 0;
}
/* 固定底部输入区域 */
.fixed-bottom-input {
  position: fixed;
  left: 0;
  right: 0;
  background: transparent;
  z-index: 900;
  padding: 0 18rpx;
  transition: bottom 0.3s ease;
  transform: translateY(0);
}

/* 功能按钮区 */
.function-buttons {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  gap: 16rpx;
  margin-bottom: 16rpx;
}

.function-btn {
  width: 160rpx;
  height: 64rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.9);
  border: 1rpx solid rgba(25, 197, 156, 0.2);
  border-radius: 32rpx;
  transition: all 0.3s ease;
  box-shadow: 0 4rpx 16rpx rgba(25, 197, 156, 0.1);
}

.function-btn:active {
  background: rgba(25, 197, 156, 0.1);
  border-color: rgba(25, 197, 156, 0.3);
  transform: scale(0.95);
}

.function-btn-text {
  font-size: 26rpx;
  color: #333;
  font-weight: 500;
}

/* 输入包装器 */
.input-wrapper {
  background: #fff;
  border: 2rpx solid #19c59c;
  border-radius: 36rpx;
  box-shadow: 0 8rpx 32rpx 0 rgba(25,197,156,0.18);
  padding: 24rpx;
}
.input-row {
  flex-direction: row;
  place-items: center;
  display: flex;
  align-items: flex-start;
  width: 100%;
  min-height: 40px;
  height: auto;
  position: relative;
}
.bottom-input {
  width: 100%;
  padding: 20rpx;
  resize: none;
  min-height: 40rpx;
  max-height: 240rpx;
  transition: height 0.2s ease;
  line-height: 48rpx;
  font-size: 32rpx;
  border: none;
  outline: none;
  color: #222;
  word-break: break-all;
  white-space: pre-wrap;
  background: transparent;
}
.tools-row {
  flex-direction: row;
  display: flex;
  align-items: center;
  padding-top: 8px;
  margin-top: 8px;
  border-top: 1px solid rgba(25,197,156,0.1);
  gap: 8px;
}
.input-attach-btn, .input-send-btn {
  width: 64rpx;
  height: 64rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 1;
  transition: all 0.2s ease;
  border-radius: 32rpx;
  background: transparent;
  border: none;
}
.input-attach-btn {
  margin-left: auto; /* 当无附件时将按钮推至右侧 */
  margin-right: 0px; /* 调整与发送按钮间距 */
  opacity: 1;
  box-shadow: none;
  border: none;
}
.input-attach-btn:active {
  background: transparent;
  box-shadow: none;
  transform: none;
  opacity: 1;
}
.input-send-btn:active {
  opacity: 1;
  background: transparent;
  transform: none;
}
.input-send-btn {
  margin-left: 16rpx;
  opacity: 1;
  box-shadow: none;
  border: none;
}
.input-send-btn:active {
  background: transparent;
  box-shadow: none;
  transform: none;
}
.input-attach-img {
  width: 48rpx;
  height: 48rpx;
  opacity: 1;
}
.input-status-img {
  width: 48rpx;
  height: 48rpx;
}
.input-attachments-list {
  display: flex;
  flex-wrap: nowrap;
  gap: 8px;
  flex-direction: row;
  max-width: 60vw;
  overflow-x: auto;
  flex: 1; /* 占据剩余空间，按钮固定右侧 */
}
.input-attachment-item {
  position: relative;
  width: 48px;
  height: 48px;
  border-radius: 4px;
  overflow: hidden;
}
.input-attachment-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.input-attachment-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
}
.input-attachment-close {
  color: #fff;
  font-size: 16px;
  font-weight: bold;
}
.msg-copy-row {
  display: flex;
  margin-top: 12rpx; /* 增加气泡与复制按钮间距 */
}
.msg-copy-row.ai {
  justify-content: flex-start;
}
.msg-copy-icon {
  width: 28rpx;
  height: 28rpx;
  opacity: 0.7;
}
.msg-copy-icon:active { opacity:1; }
.msg-image {
  max-width: 480rpx;
  max-height: 320rpx;
  border-radius: 8rpx;
  cursor: pointer;
}
.history-mask {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.4);
  z-index: 2000;
  display: flex;
  justify-content: flex-end;
}
.history-drawer {
  width: 70vw;
  height: 100vh;
  background: #fff;
  box-shadow: -4px 0 12px rgba(0,0,0,0.1);
  display: flex;
  flex-direction: column;
}
.history-header {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 24rpx;
  padding-bottom: 16rpx;
  border-bottom: 1px solid #eee;
}
.history-title { font-size: 32rpx; font-weight: bold; }
.history-list { flex: 1; padding: 24rpx; }
.history-date { font-size: 26rpx; color: #666; margin-bottom: 12rpx; display:block; }
.history-item { padding: 16rpx 0; border-bottom: 1px solid #f0f0f0; }
.history-item-title { font-size: 28rpx; color: #333; }
.thinking-line {
  color: #888;
  font-size: 28rpx;
  margin: 0 12rpx 40rpx;
}
</style>